package ${package.Controller};

import org.springframework.web.bind.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.rt.easyjava.common.base.Result;
import com.rt.easyjava.common.utils.others.DateTool;
import com.rt.easyjava.common.base.MyQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import com.rt.easyjava.common.base.UserDetailsDto;
import com.rt.easyjava.common.config.dozer.MyMapper;
import com.rt.easyjava.common.base.PageDto;
import ${cfg.package_name}.dto.${entity}Dto;
import ${cfg.package_name}.model.bean.${entity};
import ${cfg.package_name}.service.${entity}Service;
import java.util.List;

/**
 * ${table.comment!}前端控制器
 * @author ${author}
 * @since ${date}
 * 用户信息可直接形参获取：String (_userId，_loginName，_userName，_companyId，_userJson) or userDetailsDto.getUserId()
 */
@Slf4j
public class ${table.entityName}BaseController {
    @Autowired
    protected MyMapper mapper;
    @Autowired
    protected ${entity}Service ${table.entityPath}Service;

    protected Result page(${entity}Dto ${table.entityPath}Dto, UserDetailsDto userDetailsDto){
        Page<${table.entityName}> page = new Page<>(${table.entityPath}Dto.getPage(), ${table.entityPath}Dto.getLimit());

        // 查询条件
        ${table.entityName} ${table.entityPath}Query = mapper.map(${table.entityPath}Dto, ${table.entityName}.class);
        // set deleteflag default 0, 查询参数时，默认只查有效数据
        ${table.entityPath}Query.setDeleteflagDefaultZero();
        // 数据访问边界 0：全部数据， 10：机构内部数据
        ${table.entityPath}Query.rebuildDataLimitQueryBean(userDetailsDto);

        QueryWrapper<${table.entityName}> queryWrapper=new QueryWrapper<>(${table.entityPath}Query);
        //特殊查询条件
<#list cfg.conditionColumnMapList as conditionColumn>
    <#if conditionColumn.queryType=='like'>
        ${table.entityPath}Query.set${conditionColumn.propertyNameFirstWordUpper}(null);
        queryWrapper.like(${table.entityPath}Dto.get${conditionColumn.propertyNameFirstWordUpper}()!=null,"${conditionColumn.columnName}",${table.entityPath}Dto.get${conditionColumn.propertyNameFirstWordUpper}());
    <#elseif conditionColumn.queryType=='between'>
        queryWrapper.ge(${table.entityPath}Dto.get${conditionColumn.propertyNameFirstWordUpper}_Start()!=null,"${conditionColumn.columnName}",${table.entityPath}Dto.get${conditionColumn.propertyNameFirstWordUpper}_Start());
        queryWrapper.le(${table.entityPath}Dto.get${conditionColumn.propertyNameFirstWordUpper}_End()!=null,"${conditionColumn.columnName}",${table.entityPath}Dto.get${conditionColumn.propertyNameFirstWordUpper}_End());
    </#if>
</#list>
        // queryWrapper.orderBy(${table.entityPath}Dto.getCondition(), ${table.entityPath}Dto.isAsc(), ${table.entityPath}Dto.getColumn());
        // 支持前端：listQuery.sort='-part_no,-id'
        for (PageDto sortDto:${table.entityPath}Dto.getSortList()){
            queryWrapper.orderBy(true, sortDto.getAsc(), sortDto.getColumn());
        }

        return ${table.entityPath}Service.page(page, queryWrapper);
    }

    /**
        树结构查询方法，非树结构会造一个空方法备用着。
    */
    protected Result tree (Long id) {
        Result<${entity}Dto> result = new Result<>();
        // when id=0 , id=0 is parantId=0 , 默认设置一个空根
        ${entity}Dto ${table.entityPath}Dto = new ${entity}Dto();
        <#if cfg.idType?? && cfg.idType=='uuid'>
        ${table.entityPath}Dto.setId("0");
        <#else >
        ${table.entityPath}Dto.setId(0L);
        </#if>
        if (id!=0) {
            ${entity} ${table.entityPath} = ${table.entityPath}Service.getById(id);
            ${table.entityPath}Dto = mapper.map(${table.entityPath}, ${entity}Dto.class);
        }
        treeReduce(${table.entityPath}Dto);
        result.setObj(${table.entityPath}Dto);

        return result.success();
    }

    private void treeReduce(${entity}Dto ${table.entityPath}Dto){
        <#if cfg.isTreeTable == true>
        // myson list
        QueryWrapper<${entity}> queryWrapper=new QueryWrapper<>();
        // queryWrapper.eq("${cfg.tableNameFirstWordLower}_id", ${table.entityPath}Dto.getId());
        queryWrapper.eq("parent_id", ${table.entityPath}Dto.getId());
        queryWrapper.eq("deleteflag", 0);
        queryWrapper.orderByAsc(true, "id");
        List<${entity}> sonList = ${table.entityPath}Service.list(queryWrapper);
        if (sonList.size() == 0) {
            return;
        }
        List<${entity}Dto> sonDtoList = mapper.maplist(sonList, ${entity}Dto.class);

        ${table.entityPath}Dto.set${entity}List(sonDtoList);
        for (${entity}Dto dto : sonDtoList) {
            treeReduce(dto);
        }
        </#if>
    }

    protected Result myPage(${table.entityName}Dto ${table.entityPath}Dto, UserDetailsDto userDetailsDto){
        Page<${table.entityName}> page = new Page<>(${table.entityPath}Dto.getPage(), ${table.entityPath}Dto.getLimit());

        // 查询条件
        ${table.entityName} ${table.entityPath}Query = mapper.map(${table.entityPath}Dto, ${table.entityName}.class);
        // set deleteflag default 0, 查询参数时，默认只查有效数据
        ${table.entityPath}Query.setDeleteflagDefaultZero();
        // 数据访问边界 0：全部数据， 10：机构内部数据
        ${table.entityPath}Query.rebuildDataLimitQueryBean(userDetailsDto);

        // 多表查询时，plus自带不支持，这里封装一个工具类处理，mapper.xml中主表别名是t1, 给所有非空字段加别名； 特殊查询条件，在工具类中要忽略掉，最后自定义增加。
        QueryWrapper<${table.entityName}> queryWrapper = MyQueryWrapper.buildQueryWrapper(${table.entityPath}Query <#list cfg.conditionColumnMapList as conditionColumn><#if conditionColumn.queryType=='like' || conditionColumn.queryType=='between'>, "${conditionColumn.columnName}"</#if></#list>);
        //特殊查询条件
    <#list cfg.conditionColumnMapList as conditionColumn>
    <#if conditionColumn.queryType=='like'>
        queryWrapper.like(${table.entityPath}Dto.get${conditionColumn.propertyNameFirstWordUpper}()!=null,"t1.${conditionColumn.columnName}",${table.entityPath}Dto.get${conditionColumn.propertyNameFirstWordUpper}());
    <#elseif conditionColumn.queryType=='between'>
        queryWrapper.ge(${table.entityPath}Dto.get${conditionColumn.propertyNameFirstWordUpper}_Start()!=null,"t1.${conditionColumn.columnName}",${table.entityPath}Dto.get${conditionColumn.propertyNameFirstWordUpper}_Start());
        queryWrapper.le(${table.entityPath}Dto.get${conditionColumn.propertyNameFirstWordUpper}_End()!=null,"t1.${conditionColumn.columnName}",${table.entityPath}Dto.get${conditionColumn.propertyNameFirstWordUpper}_End());
    </#if>
    </#list>
        // queryWrapper.orderBy(${table.entityPath}Dto.getCondition(), ${table.entityPath}Dto.isAsc(), "t1."+${table.entityPath}Dto.getColumn());
        // 支持前端：listQuery.sort='-part_no,-id'
        for (PageDto sortDto:${table.entityPath}Dto.getSortList()){
            queryWrapper.orderBy(true, sortDto.getAsc(), "t1."+sortDto.getColumn());
        }

        return ${table.entityPath}Service.myPage(page, queryWrapper, ${table.entityPath}Dto.getHasFooter());
    }

    protected Result selectBy(${table.entityName}Dto ${table.entityPath}Dto, UserDetailsDto userDetailsDto){
        Result<${table.entityName}Dto> result = new Result<>();

        // 查询条件
        ${table.entityName} ${table.entityPath}Query = mapper.map(${table.entityPath}Dto, ${table.entityName}.class);
        // set deleteflag default 0, 查询参数时，默认只查有效数据
        ${table.entityPath}Query.setDeleteflagDefaultZero();
        // 数据访问边界 0：全部数据， 10：机构内部数据
        ${table.entityPath}Query.rebuildDataLimitQueryBean(userDetailsDto);

        QueryWrapper<${table.entityName}> queryWrapper=new QueryWrapper<>(${table.entityPath}Query);
        //特殊查询条件
    <#list cfg.conditionColumnMapList as conditionColumn>
    <#if conditionColumn.queryType=='like'>
        ${table.entityPath}Query.set${conditionColumn.propertyNameFirstWordUpper}(null);
        queryWrapper.like(${table.entityPath}Dto.get${conditionColumn.propertyNameFirstWordUpper}()!=null,"${conditionColumn.columnName}",${table.entityPath}Dto.get${conditionColumn.propertyNameFirstWordUpper}());
    <#elseif conditionColumn.queryType=='between'>
        queryWrapper.ge(${table.entityPath}Dto.get${conditionColumn.propertyNameFirstWordUpper}_Start()!=null,"${conditionColumn.columnName}",${table.entityPath}Dto.get${conditionColumn.propertyNameFirstWordUpper}_Start());
        queryWrapper.le(${table.entityPath}Dto.get${conditionColumn.propertyNameFirstWordUpper}_End()!=null,"${conditionColumn.columnName}",${table.entityPath}Dto.get${conditionColumn.propertyNameFirstWordUpper}_End());
    </#if>
    </#list>
        queryWrapper.orderBy(${table.entityPath}Dto.getCondition(), ${table.entityPath}Dto.isAsc(), ${table.entityPath}Dto.getColumn());

        result = ${table.entityPath}Service.selectBy(queryWrapper);

        return result;
    }

    protected Result selectById(Long id){
        return ${table.entityPath}Service.selectById(id);
    }

    protected Result select4column(String columnName){
        return ${table.entityPath}Service.select4column(columnName);
        <#--try {
            // vue默认传过来的，出于枚举类名考虑，首字母是大写，这样要小字当属性用。
            columnName = columnName.substring(0,1).toLowerCase()+columnName.substring(1);
            Object o = SpringContextHolder.getBean("${table.entityPath}Service");
            Method method = o.getClass().getMethod("mySelect4"+columnName);
            return Result.builder(method.invoke(o)).success();
        }catch (Exception e){
            throw new RuntimeException("方法名不存在");
        }-->
    }

    protected Result create(@RequestBody ${table.entityName}Dto ${table.entityPath}Dto,
                    String _userId, String _userName, String _companyId){
        //插入参数
        ${table.entityPath}Dto.setCreatemanId(Long.parseLong(_userId));
        ${table.entityPath}Dto.setCreateman(_userName);
        ${table.entityPath}Dto.setCreatedate(DateTool.getCurrentDatetime());
        ${table.entityPath}Dto.setCompanyId(Long.parseLong(_companyId));
        ${table.entityPath}Dto.setVersion(0L);

        //调用服务
        return ${table.entityPath}Service.create(${table.entityPath}Dto);
    }

    protected Result update(@RequestBody ${table.entityName}Dto ${table.entityPath}Dto,
                        String _userId, String _userName){
        try{
            ${table.entityPath}Dto.getId().longValue();
        }catch (Exception e){
            return Result.builder().fault("数据中缺少ID");
        }

        //参数
        ${table.entityPath}Dto.setModifymanId(Long.parseLong(_userId));
        ${table.entityPath}Dto.setModifyman(_userName);
        ${table.entityPath}Dto.setModifydate(DateTool.getCurrentDatetime());
        ${table.entityPath}Dto.setCreatedate(null);
        ${table.entityPath}Dto.setCreateman(null);
        ${table.entityPath}Dto.setCreatemanId(null);
        ${table.entityPath}Dto.setCompanyId(null);

        <#--//query condition for update
        UpdateWrapper updateWrapper = new UpdateWrapper();
        updateWrapper.eq("id", ${table.entityPath}Dto.getId()==null?"0":${table.entityPath}Dto.getId());-->

        //调用服务
        return ${table.entityPath}Service.updateByDtoId(${table.entityPath}Dto);
    }

    protected Result delete(Long id, String _userId, String _userName){
        try{
            id.longValue();
        }catch (Exception e){
            return Result.builder().fault("数据中缺少ID");
        }
        //参数
        ${table.entityName}Dto ${table.entityPath}Dto = new ${table.entityName}Dto();
        ${table.entityPath}Dto.setModifymanId(Long.parseLong(_userId));
        ${table.entityPath}Dto.setModifyman(_userName);
        ${table.entityPath}Dto.setModifydate(DateTool.getCurrentDatetime());
        ${table.entityPath}Dto.setDeleteflag("1");

        <#--//query condition for update
        UpdateWrapper updateWrapper = new UpdateWrapper();
        updateWrapper.eq("id", id==null?0:id.longValue());-->
        //调用服务
        return ${table.entityPath}Service.updateByDtoId(${table.entityPath}Dto);
    }

    protected Result deletePhysical(Long id){
        Result result = new Result();

        //调用服务
        Boolean aBoolean =  false;//${table.entityPath}Service.removeById(id==null?0:id.longValue());
        if(aBoolean){
            result.success();
        }else {
            result.fault();
        }

        return result;
    }

}
